<?php
/*
 * [JINYUN!] (C)2001-2099 Jinyunweb.com
 * This is NOT a freeware, use is subject to license terms
 * $Id: 2017-12-13 03:39:35 apple $
*/
namespace jy_wechatnews;
defined('BY_JYA') or exit('error');
/*
	插件工具类
*/
class wechat extends \plugin{
	protected $wechat = null;
	public function __construct($listid=0){
		$this->wechat=pdo_get('jy_wechatnews_list',array('uniacid'=>$_SESSION['uniacid'],'id'=>$listid));
		if(!$listid){
			$listid=$_SESSION['listid'];
		}
		//没有添加公众号，也能访问，调用系统公众号
		if(empty($this->wechat)){
			exi('找不到指定公众号','error');
		}
		if (empty($this->wechat['appid'])){
			exi('未填写公众号appid','error');
		}
		//如果公众号为普通模式添加并且未借用，APPsecret为必填项
		if(!$this->wechat['appsecret']){
			exi('未填写公众号appsecret','error');
		}
		if($this->wechat['expire']<TIMESTAMP){
			$this->getAccessToken();
		}
	}
	public function getAccessToken($isup=false){//获取access_token
		global $_AR;
		if($this->wechat['expire']>TIMESTAMP && !$isup && $this->wechat['up_tokentime']<TIMESTAMP-600){
			return $this->wechat['access_token'];
		}
		$url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={$this->wechat['appid']}&secret={$this->wechat['appsecret']}";
		$content = cfc('http')->ihttp_request($url);
		if(is_error($content)){
			exi('获取微信公众号授权失败, 请稍后重试！错误详情：'.$content['message'],'error');
		}
		$token = @json_decode($content['content'], true);
		if(empty($token) || empty($token['access_token'])){
			if($token['errcode']!='45009'){
				exi('获取微信公众号授权失败, 请稍后重试！ 公众平台返回原始数据为: 错误代码-' . $token['errcode'] . '，错误信息-' . $token['errmsg'].'错误详情：'.$this->error_code($token['errcode']),'error');
			}
			exi('获取微信公众号授权失败, 请稍后重试！错误详情：'.$content['message'],'error');
			return false;
		}
		if($token['access_token']){
			$token['expires_in']=$token['expires_in']?:7200;
			$record = array('up_tokentime'=>TIMESTAMP);
			$record['access_token'] = $token['access_token'];
			$record['expire'] = TIMESTAMP + $token['expires_in'] - 200;
			pdo_update('jy_wechatnews_list',$record,array('uniacid'=>$_SESSION['uniacid'],'id'=>$this->wechat['id']));
			$this->wechat['access_token']=$token['access_token'];
		}
		return $token['access_token'];
	}
	//发起http请求
	public function request($url,$post=null,$continue=true,$direct=false,$return_error=false,$return_data=false){
		if($this->return_error_one){
			$return_error=true;
			$this->return_error_one=false;
		}
		if($this->return_error){
			$return_error=true;
		}
		$rurl=str_replace(array('{access_token}','ACCESS_TOKEN'),$this->wechat['access_token'],$url);
		if($post){
			$result=cfc('http')->ihttp_request($rurl,$post);
		}else{
			$result=cfc('http')->ihttp_get($rurl);
		}
		if(is_error($result)){
			$message="访问公众平台接口失败, 错误: {$result['message']}";
			if($return_error){
				return error($message);
			}else{
				exi($message,'error');
			}
		}
		$data=preg_replace('/[\x00-\x1F]/','',$result['content']);
		$data=@json_decode($data,true);
		if($data['errcode']=='42001' && $continue){
			$this->getAccessToken(true);
			$data=$this->request($url,$post,false,$direct,$return_error);
			return $data;
		}
		if($data['errcode']){
			if($return_data){
				return $data;
			}
			$message="访问微信接口错误, 错误代码: {$data['errcode']}, 错误信息: {$data['errmsg']},错误详情：{$this->error_code($data['errcode'])}";
			if($return_error || $_SESSION['this']=='custom'){
				return error($message);
			}else{
				exi($message,'error');
			}
		}
		if($direct){
			return $result;
		}
		if(!is_array($data) || !$data){
			$message='访问微信接口错误，以下为原始数据：'.$result['content'];
			if($return_error){
				return error($message);
			}else{
				exi($message,'error');
			}
		}
		return $data;
	}
	public function fabu($news=array()){
		//发布文章
		$media_id=$this->add($news);
		$api='https://api.weixin.qq.com/cgi-bin/freepublish/submit?access_token={access_token}';
		$post=array('media_id'=>$media_id);
		$result=$this->request($api,ijson_encode($post));
		if(!$result['errcode']){
			pdo_update('jy_wechatnews_news',array('status'=>4,'publish_id'=>$result['publish_id'],'sendtime'=>time()),array('uniacid'=>$_SESSION['uniacid'],'id'=>$news['id']));
		}else{
			exi('文章发布公众号失败！'.$result['errmsg'],'error');
		}
		return $result;
	}
	public function add($news=array()){
		//新增草稿箱
		$api='https://api.weixin.qq.com/cgi-bin/draft/add?access_token={access_token}';	
		$newsarticles=array();
		if(!$news['image']){
			exi('文章图片不存在，不能发布！','error');
		}
		$temp=array(
				'title'=>$news['title'],
				'thumb_media_id'=>$this->add_media($news['image'],1),
				'show_cover_pic'=>true,
				'content_source_url'=>custom_url(array('jy_wechatnews/newsitem//id='.$news['id']),true),
		);
		//文章内容整理
		preg_match_all('/src="([^"]+)"/',$news['content'],$matchs);
		if($matchs['1']){
			//如果有检测到图片，则替换之
			$search=array();$replace=array();
			foreach($matchs['1'] as $src){
					if(!in_array($src,$search)){
						$search[]=$src;
						$replace[]=$this->add_media_news_image($src);
						
					}
			}
			$temp['content']=str_replace($search,$replace,$news['content']);
		}else{
			$temp['content']=$news['content'];
		}
		$newsarticles[]=$temp;
		$post=array('articles'=>$newsarticles);
		$result=$this->request($api,ijson_encode($post));
		if($result['type']=='error'){
			exi('新增草稿失败！'.$result['message'],'error');
		}
		pdo_update('jy_wechatnews_news',array('media_id'=>$result['media_id'],'thumb_media_id'=>$temp['thumb_media_id']),array('uniacid'=>$_SESSION['uniacid'],'id'=>$news['id']));
		return $result['media_id'];
	}
	//上传图文消息内的图片获取URL【订阅号与服务号认证后均可用】
	public function add_media_news_image($source){
	    $api='https://api.weixin.qq.com/cgi-bin/media/uploadimg?access_token={access_token}';
		$ext=strrchr($source,'.');
		$source=tomedia($source);
		$temp=ROOT_AT.random(30).$ext;
		copy($source,$temp);
	    $post=array('media'=>'@'.$temp);
	    $result=$this->request($api,$post);
		if(!$result['url']){
			exi('图文消息错误！'.$res['message'],'error');
		}
		@unlink($temp);
		return $result['url'];
	}
	//新增永久素材，除图文素材外，返回素材ID  根据附件本地地址获取素材ID
	public function add_media($source,$type,$source_title='未设置',$title='视频标题',$introduction='视频描述') {
		//参数说明：附件相对地址，素材类型
		$types=array(
			'1'=>'image',
			'2'=>'voice',
			'3'=>'video',
		);
		//检测附件是否存在于素材，如果存在直接返回素材ID
		$check=pdo_getcolumn('core_media',array('uniacid'=>$_SESSION['uniacid'],'wxgid'=>$this->wechat['id'],'type'=>$type,'attachment'=>$source),'media_id');
		if($check){
			return $check;
		}
		$url='https://api.weixin.qq.com/cgi-bin/material/add_material?access_token={access_token}&type='.$types[$type];
		$ext=strrchr($source,'.');		
		$ext=strtolower($ext);
		if(ATTACHMENT_TYPE){
			//远程附件
			$source=tomedia($source);
			$temp=ROOT_AT.random(30).$ext;
			copy($source,$temp);
		}else{
			$temp=ROOT_AT.$source;
		}
		//检测素材格式和大小是否合法
		$size=filesize($temp);
		switch($type){
			case 1:
				$yes=in_array($ext,array('.png','.peg','.jpg','.gif','.jpeg')) && $size<=2*1024*1024;
				break;
			case 2:
				$yes=in_array($ext,array('.amr','.mp3')) && $size<=2*1024*1024;
				break;
			case 3:
				$yes=in_array($ext,array('.mp4')) && $size<=10*1024*1024;
				break;
		}
		if(!$yes){
			exi('素材格式或者大小错误！'.$type.$ext.$size,'error');
		}
		if($type==3){
			$post=array('media'=>'@'.$temp);
			$post['description']=ijson_encode(array('title'=>$title,'introduction'=>$introduction));
		}else{
			$post=array('media'=>'@'.$temp);
		}
		$res=$this->request($url,$post);
		if(ATTACHMENT_TYPE){
			@unlink($temp);
		}
		if(!$res['media_id']){
			exi('素材错误！'.$res['message'],'error');
		}
		//将素材入库
		$insert=array(
			'uniacid'=>$_SESSION['uniacid'],
			'wxgid'=>$this->wechat['id'],
			'type'=>$type,
			'createtime'=>TIMESTAMP,
			'attachment'=>$source,
			'content'=>$res['media_id'],
			'title'=>$source_title,
			'media_id'=>$res['media_id'],
			'url'=>$res['url'],
		);
		pdo_insert('core_media',$insert);
		return $res['media_id'];
	}
	//错误码
	public function error_code($code, $errmsg = '未知错误') {//获取错误详情
		global $_AR;
		$errors = array(
			'-1' => '系统繁忙',
			'0' => '请求成功',
			'40001' => '获取access_token时AppSecret错误，或者access_token无效',
			'40002' => '不合法的凭证类型',
			'40003' => '不合法的OpenID',
			'40004' => '不合法的媒体文件类型',
			'40005' => '不合法的文件类型',
			'40006' => '不合法的文件大小',
			'40007' => '不合法的媒体文件id',
			'40008' => '不合法的消息类型',
			'40009' => '不合法的图片文件大小',
			'40010' => '不合法的语音文件大小',
			'40011' => '不合法的视频文件大小',
			'40012' => '不合法的缩略图文件大小',
			'40013' => '不合法的APPID',
			'40014' => '不合法的access_token',
			'40015' => '不合法的菜单类型',
			'40016' => '不合法的按钮个数',
			'40017' => '不合法的按钮个数',
			'40018' => '不合法的按钮名字长度',
			'40019' => '不合法的按钮KEY长度',
			'40020' => '不合法的按钮URL长度',
			'40021' => '不合法的菜单版本号',
			'40022' => '不合法的子菜单级数',
			'40023' => '不合法的子菜单按钮个数',
			'40024' => '不合法的子菜单按钮类型',
			'40025' => '不合法的子菜单按钮名字长度',
			'40026' => '不合法的子菜单按钮KEY长度',
			'40027' => '不合法的子菜单按钮URL长度',
			'40028' => '不合法的自定义菜单使用用户',
			'40029' => '不合法的oauth_code',
			'40030' => '不合法的refresh_token',
			'40031' => '不合法的openid列表',
			'40032' => '不合法的openid列表长度',
			'40033' => '不合法的请求字符，不能包含\uxxxx格式的字符',
			'40035' => '不合法的参数',
			'40038' => '不合法的请求格式',
			'40039' => '不合法的URL长度',
			'40050' => '不合法的分组id',
			'40051' => '分组名字不合法',
			'41001' => '缺少access_token参数',
			'41002' => '缺少appid参数',
			'41003' => '缺少refresh_token参数',
			'41004' => '缺少secret参数',
			'41005' => '缺少多媒体文件数据',
			'41006' => '缺少media_id参数',
			'41007' => '缺少子菜单数据',
			'41008' => '缺少oauth code',
			'41009' => '缺少openid',
			'42001' => 'access_token超时',
			'42002' => 'refresh_token超时',
			'42003' => 'oauth_code超时',
			'43001' => '需要GET请求',
			'43002' => '需要POST请求',
			'43003' => '需要HTTPS请求',
			'43004' => '需要接收者关注',
			'43005' => '需要好友关系',
			'44001' => '多媒体文件为空',
			'44002' => 'POST的数据包为空',
			'44003' => '图文消息内容为空',
			'44004' => '文本消息内容为空',
			'45001' => '多媒体文件大小超过限制',
			'45002' => '消息内容超过限制',
			'45003' => '标题字段超过限制',
			'45004' => '描述字段超过限制',
			'45005' => '链接字段超过限制',
			'45006' => '图片链接字段超过限制',
			'45007' => '语音播放时间超过限制',
			'45008' => '图文消息超过限制',
			'45009' => '接口调用超过限制',
			'45010' => '创建菜单个数超过限制',
			'45015' => '回复时间超过限制',
			'45016' => '系统分组，不允许修改',
			'45017' => '分组名字过长',
			'45018' => '分组数量超过上限',
			'45030' => '该cardid无接口权',
			'45056' => '创建的标签数过多，请注意不能超过100个',
			'45057' => '该标签下粉丝数超过10w，不允许直接删除',
			'45058' => '不能修改0/1/2这三个系统默认保留的标签',
			'45059' => '有粉丝身上的标签数已经超过限制',
			'45157' => '标签名非法，请注意不能和其他标签重名',
			'45158' => '标签名长度超过30个字节',
			'45159' => '非法的标签',
			'46001' => '不存在媒体数据',
			'46002' => '不存在的菜单版本',
			'46003' => '不存在的菜单数据',
			'46004' => '不存在的用户',
			'47001' => '解析JSON/XML内容错误',
			'48001' => 'api 功能未授权，请确认公众号已获得该接口，可以在公众平台官网 - 开发者中心页中查看接口权限',
			'50001' => '用户未授权该api',
			'40070' => '基本信息baseinfo中填写的库存信息SKU不合法。',
			'41011' => '必填字段不完整或不合法，参考相应接口。',
			'40056' => '无效code，请确认code长度在20个字符以内，且处于非异常状态（转赠、删除）。',
			'43009' => '无自定义SN权限，请参考开发者必读中的流程开通权限。',
			'43010' => '无储值权限,请参考开发者必读中的流程开通权限。',
			'43011' => '无积分权限,请参考开发者必读中的流程开通权限。',
			'40078' => '无效卡券，未通过审核，已被置为失效。',
			'40079' => '基本信息base_info中填写的date_info不合法或核销卡券未到生效时间。',
			'45021' => '文本字段超过长度限制，请参考相应字段说明。',
			'40080' => '卡券扩展信息cardext不合法。',
			'40097' => '基本信息base_info中填写的参数不合法。',
			'49004' => '签名错误。',
			'43012' => '无自定义cell跳转外链权限，请参考开发者必读中的申请流程开通权限。',
			'40099' => '该code已被核销。',
			'61005' => '缺少接入平台关键数据，等待微信开放平台推送数据，请十分钟后再试或是检查“授权事件接收URL”是否写错（index.php?c=account&amp;a=auth&amp;do=ticket地址中的&amp;符号容易被替换成&amp;amp;）',
			'61023' => '请重新授权接入该公众号',
			'85005'=>'小程序未关联公众号，无法通过自定义菜单跳转！',
			'40164'=>'服务器IP不在白名单导致接口请求失败！请前往公众平台——开发——基本配置——公众号开发信息——IP白名单处设置',
		);
		$code = strval($code);
		if($errors[$code]) {
			return $errors[$code];
		} else {
			return $errmsg;
		}
	}
}